/**
 * Created with  SublimeText
 * @Author:      chenweihan
 * @DateTime:    2018-4-27 22:05:07
 * @Description: api 多节点控制，支持同一个请求，短时间重复的过滤
 */
import axios from 'axios';
import qs from 'qs';
import config from '@/config';
import md5 from 'md5';

//发送请求的管理，同一请求在没有返回的情况下或者超时返回，不能反复请求
let requestManagement = {};
const CancelToken = axios.CancelToken;

//API 全局配置
axios.defaults.baseURL = config.apiUrl;
axios.defaults.timeout = 60000;
axios.defaults.withCredentials = true;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.transformRequest = [function(data) {
    //console.log(qs.stringify(data));
    //return a string or an instance of Buffer, ArrayBuffer,FormData or Stream
    return qs.stringify(data);
    //return data;
}];

//请求拦截器
axios.interceptors.request.use(function(config) {
    //console.log('request', config);
    requestUrl(config);
    return config
}, function(error) {
    return Promise.reject(error);
});

//返回拦截器
axios.interceptors.response.use(function(response) {
    //console.log('response', response);
    responseUrl(response.config);
    return response;
}, function(error) {
    return Promise.reject(error);
});

/*
 * 拦截相同API  测试在test模块中
 * 存在2个模块初始化都请求一个API，会存在问题，这类情况很少，注意即可。
 * 暴露请求状态对象出去，可以控制每个请求的状态，(切换路由终止/时间长度终止）
 * 建议：有些是依赖初始化异步懒加载，发送成功后，人为终止或许更多问题需要处理, 比如增加白名单
 */
function requestUrl(config) {
    let requestId = md5(config.url+config.data);
    if (requestManagement[requestId]) {
        config.cancelRequest('阻塞重复异步请求#'+config.url);
    } else {
        requestManagement[requestId] = {cancel:config.cancelRequest,createTime:new Date()};
        /* 测试请求发送成功后又取消，测试是OK的
        setTimeout(function(){
            config.cancelRequest('测试发送出去后，在终止请求');
        },100);
        */
    }
    config.requestId = requestId;
}

function responseUrl(config) {
    if (requestManagement[config.requestId]) {
        delete requestManagement[config.requestId];
    } 
}

//暴露出去
export function getHttpStatus() {
    return requestManagement;
}

//axios
function requestEntrance(data, callback) {
    if (typeof(callback) === 'object') {
        callback.success = callback.success || function() {};
        callback.error = callback.error || function() {};
        callback.complete = callback.complete || function() {};
        data.cancelToken = new CancelToken(c => {
            data.cancelRequest = c;
        });
        return axios(data)
            .then(function(response) {
                callback.complete(response);
                if (response) {
                    callback.success(response.data);
                }
            })
            .catch(function(error) {
                if (axios.isCancel(error)) {
                    console.log('Request canceled', error.message);
                } else {
                    callback.complete(error);
                    callback.error(error);
                    alert('Oops! There was a problem on the request. Please check the ' + data.url);
                    console.log('error:', data.url, error);
                }
            });
    }
}

/****************************** api **************************/
//下面的API可以按照模块分解也可以集中管理,各有优势

//API test
export function test(obj) {
    let requestData = {
            method: 'post',
            url: '/test',
            data: obj.data
        },
        requestCallback = {};
    requestCallback.success = function(response) {
        obj.success ? obj.success(response) : '';
    };
    requestEntrance(requestData, requestCallback); 
}

//API login
export function login(obj) {
    let requestData = {
            method: 'post',
            url: '/user/login',
            data: obj.data
        },
        requestCallback = {};
    requestCallback.success = function(response) {
        obj.success ? obj.success(response) : '';
    };
    requestEntrance(requestData, requestCallback);
}

//API searchMerchant
export function searchMerchant(obj) {
    let requestData = {
            method: 'post',
            url: '/merchant/searchMerchant',
            data: obj.data
        },
        requestCallback = {};
    requestCallback.success = function(response) {
        obj.success ? obj.success(response) : '';
    };
    requestEntrance(requestData, requestCallback);
}